#pragma once
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

class wordcounter
{
private:
	map<string, int> words;

	struct compare
	{
	public:
		bool operator()(const pair<string, int> &lop, const pair<string, int> & rop) const
		{ 
			return lop.second < rop.second; 
		}
	} comp;
public:

	wordcounter()
	{
	}

	~wordcounter()
	{
	}

	void read_from_file(string filename)
	{
		if (!words.empty())
			words.clear();
		string str;
		try
		{
			ifstream fin(filename);
			while (!fin.eof())
			{
				fin >> str;
				auto it = words.find(str);
				if (it != words.end())
					it->second++;
				else
					words.emplace(str, 1);
			}
			fin.close();
		}
		catch (exception e)
		{
			cout << e.what() << endl;
		}
	}

	void most_common()
	{
		auto it = max_element(words.begin(), words.end(), comp);
		cout << "Most common word: " << it->first << " appears: " << it->second << " times" << endl; 
	}

	void top_twenty()
	{
		priority_queue<pair<string, int>, vector<pair<string,int>>, compare> queue(words.begin(), words.end());
		for (int i = 0; i < 20; i++)
		{
			cout << i << ": " << queue.top().first << " appears: " << queue.top().second << endl;
			queue.pop();
		}
	}
};

